package com.mxx.common.netty.http.validate;

import com.mxx.common.netty.http.NettyMethod;
import com.mxx.common.netty.http.NettyMethodParameter;
import com.mxx.common.utils.Strings;
import org.springframework.core.MethodParameter;
import org.springframework.validation.annotation.Validated;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;

/**
 * @author: mxx
 * @date: 2021/9/24
 * @time: 15:21
 * @Description: 描述信息
 */

public class JavaxMethodValidator implements ParameterValidator {

    private Validator validator;

    public JavaxMethodValidator(ValidatorFactory factory) {
        this.validator = factory.getValidator();
    }

    @Override
    public boolean match(NettyMethod method) {
        for (NettyMethodParameter methodParameter : method.getMethodParameters()) {
            if (methodParameter.getAnnotation(Validated.class) != null) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void validate(NettyMethod method, Object[] parameter) throws ConstraintViolationException {
        NettyMethodParameter[] methodParameters = method.getMethodParameters();
        for (int i = 0; i < methodParameters.length; i++) {
            NettyMethodParameter methodParameter = methodParameters[i];
            Validated validated = methodParameter.getAnnotation(Validated.class);
            if (validated != null) {
                Class[] groups = validated.value();
                Set<ConstraintViolation<Object>> violations = validator.validate(parameter[i], groups);
                if (!violations.isEmpty()) {
                    throw new ConstraintViolationException(Strings.join(", ", violations.stream().map(ConstraintViolation::getMessage).distinct().toArray()), violations);
                }
            }
        }
    }
}
